package com.hulizuofang.wol.chat.server.handler;

import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.google.inject.Inject;
import com.gwtplatform.dispatch.server.ExecutionContext;
import com.gwtplatform.dispatch.server.actionhandler.ActionHandler;
import com.gwtplatform.dispatch.shared.ActionException;
import com.hulizuofang.wol.chat.client.action.LoginAction;
import com.hulizuofang.wol.chat.client.action.LoginAction.LoginWorker;
import com.hulizuofang.wol.chat.client.action.LoginResult;
import com.hulizuofang.wol.chat.client.data.ChatUser;
import com.hulizuofang.wol.chat.server.ChatUserRepository;
import com.hulizuofang.wol.chat.server.channel.ChannelProvider;

public class LoginActionHandler implements ActionHandler<LoginAction, LoginResult> {

	private static final Logger logger = Logger.getLogger(LoginActionHandler.class.getName());
	
	private final ChannelProvider provider;
	private final ChatUserRepository chatUserProvider;

	@Inject
	public LoginActionHandler(ChannelProvider provider, ChatUserRepository chatUserProvider) {
		this.provider = provider;
		this.chatUserProvider = chatUserProvider;
	}

	@Override
	public LoginResult execute(LoginAction action,
			ExecutionContext context) throws ActionException {
		return action.workLogin(new LoginWorker<LoginResult>() {
			@Override
			public LoginResult work(String login) {
				try {
					if (logger.isLoggable(Level.INFO)) {
						String msg = String.format("work on LoginAction for login: %s", login);
						logger.info(msg);
					}
					
					ChatUser user = chatUserProvider.login(login);
					Set<ChatUser> onlineUsers = chatUserProvider.getOnlineUsers(login);
					String token = provider.getToken(user);
					
					for (ChatUser chatUser : onlineUsers) {						
						provider.tellIsOnline(user, chatUser);
					}
					
					return new LoginResult(user, token, onlineUsers);
				} catch (IllegalStateException e) {
					logger.log(Level.SEVERE, "While working on login", e);
					throw e;
				}
			}
		});

	}

	@Override
	public Class<LoginAction> getActionType() {return LoginAction.class;}
	@Override
	public void undo(LoginAction action, LoginResult result, ExecutionContext context) throws ActionException {}

}
